﻿using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Prism.ViewModel;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using SampleApplication2.Constants;
using SampleApplication2.Views.Ribbon;
using SampleApplication2.Views.Tools;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace SampleApplication2.Views.Shell
{
  public class MainWindowViewModel : NotificationObject
  {
    #region IRegionManager RegionManager

    IRegionManager RegionManager
    {
      get { return ServiceLocator.Current.GetInstance<IRegionManager>(); }
    }

    #endregion

    #region HomeTab HomeTab

    HomeTab HomeTab
    {
      get { return ServiceLocator.Current.GetInstance<HomeTab>(); }
    }

    #endregion

    #region ICommand LoadedCommand

    DelegateCommand<EventArgs> _loadedCommand;
    public ICommand LoadedCommand
    {
      get { return _loadedCommand ?? (_loadedCommand = new DelegateCommand<EventArgs>(OnLoaded)); }
    }

    private void OnLoaded(EventArgs args)
    {
      Initialize();
    }

    #endregion

    void Initialize()
    {
      IUnityContainer container = ServiceLocator.Current.GetInstance<IUnityContainer>();

      //NOTE:  Add an instance of our views and viewmodels to the container.  This ensures that we use the same instance everywhere we might require the view/viewmodel (Only for the ones we only want one instance of)
      //NOTE:  I tend to use MEF, so I am not sure if this is the correct way to inject object instances into Unity???
      container.RegisterInstance<MainWindowViewModel>(this);

      container.RegisterInstance<HomeTabViewModel>(new HomeTabViewModel());
      container.RegisterInstance<HomeTab>(new HomeTab());

      RegionManager.Regions[RegionNames.RibbonRegion].Add(HomeTab);

      //NOTE: Register your views and viewmodels in a container using an interface & a name
      //NOTE: Register the ViewModel first, so it is available for injection in the view's constructor.
      container.RegisterInstance<IToolViewModel>(RecentFilesViewModel.CONTENT_ID, new RecentFilesViewModel());
      container.RegisterInstance<IToolView>(RecentFilesViewModel.CONTENT_ID, new RecentFilesView());
      container.RegisterInstance<IToolViewModel>(FileStatsViewModel.CONTENT_ID, new FileStatsViewModel());
      container.RegisterInstance<IToolView>(FileStatsViewModel.CONTENT_ID, new FileStatsView());



      /////////////////////////
      // Usage Examples:
      /////////////////////////

      //Get the references to your viewmodels or views from the container.  You can use this anywhere, even in a different assembly
      //The same instances that you registered above will always be returned.
      RecentFilesViewModel rfvm1 = (RecentFilesViewModel)ServiceLocator.Current.GetInstance<IToolViewModel>(RecentFilesViewModel.CONTENT_ID);
      RecentFilesView rfv1 = (RecentFilesView)ServiceLocator.Current.GetInstance<IToolView>(RecentFilesViewModel.CONTENT_ID);
      FileStatsViewModel fsvm1 = (FileStatsViewModel)ServiceLocator.Current.GetInstance<IToolViewModel>(FileStatsViewModel.CONTENT_ID);
      FileStatsView fsv1 = (FileStatsView)ServiceLocator.Current.GetInstance<IToolView>(FileStatsViewModel.CONTENT_ID);

      //Get the references to your viewmodels or views from the container.  You can use this anywhere, even in a different assembly
      //The same instances that you registered above will always be returned.
      foreach (IToolViewModel tvm in ServiceLocator.Current.GetAllInstances<IToolViewModel>())
      {
        Debug.WriteLine("ViewModel: {0} - ({1})", tvm.GetType(), tvm.ContentId);
      }

      foreach (IToolView tv in ServiceLocator.Current.GetAllInstances<IToolView>())
      {
        Debug.WriteLine("View: {0}", tv.GetType());
      }
    }
  }
}
